package com.huoyun.util;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.AndFileFilter;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.NotFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;

public final class FileUtil {

	// 上传车辆证件保存路径
	public final static String UPLOAD_LICENSE_DIR = "/upload/licenseFiles";

	// 上传用户头像的临时文件保存路径
	public final static String UPLOAD_AVATAR_DIR = "/upload/userImages";

	// 用户实名认证时上传的身份证照片保存路径
	public final static String UPLOAD_CARD_DIR = "/upload/cardImages";

	// 上传用户头像的临时文件保存路径
	public final static String TEMP_UPLOAD_AVATAR_DIR = "/upload/temp_userImages";

	// 公司logo图片保存路径
	public final static String UPLOAD_LOGO_DIR = "/upload/companyLogoes";

	/**
	 * 图片截取
	 * 
	 * @param file
	 *            源文件
	 * @param newName
	 *            截取后的文件名称
	 * @param path
	 *            截取后的文件存放路径
	 * @param x
	 *            截取起始点的x坐标值
	 * @param y
	 *            截取起始点的y坐标值
	 * @param width
	 *            截取的宽度
	 * @param height
	 *            截取的高度
	 * @return 截取后的文件
	 * @throws IOException
	 */
	public static File cutting(File file, String newName, String path, int x,
			int y, int width, int height) throws IOException {
		ImageOutputStream out = null;
		InputStream is = null;
		ImageInputStream iis = null;
		double widthProportion = getImgWidthProportion(file);
		double heigthProportion = getImgHeigthProportion(file);
		x = (int) (x * widthProportion);
		y = (int) (y * heigthProportion);
		width = (int) (width * widthProportion);
		height = (int) (height * heigthProportion);

		try {
			String endName = file.getName();
			endName = endName.substring(endName.lastIndexOf(".") + 1);
			Iterator<ImageReader> readers = ImageIO
					.getImageReadersByFormatName(endName);
			ImageReader reader = (ImageReader) readers.next();
			is = new FileInputStream(file);
			iis = ImageIO.createImageInputStream(is);

			reader.setInput(iis, true);

			ImageReadParam param = reader.getDefaultReadParam();
			Rectangle rect = new Rectangle(x, y, width, height);
			param.setSourceRegion(rect);
			BufferedImage bi = reader.read(0, param);
			File newFile = new File(path);

			if (!newFile.exists())
				newFile.mkdirs();
			newFile = new File(path, newName);
			out = ImageIO
					.createImageOutputStream(new FileOutputStream(newFile));
			ImageIO.write(bi, endName, out);
			file = newFile;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			iis.close();
			is.close();
			out.close();
		}
		return file;
	}

	public static double getImgWidthProportion(File file)
			throws FileNotFoundException, IOException {
		BufferedImage oldBufferedImage = ImageIO
				.read(new FileInputStream(file));
		return oldBufferedImage.getWidth() / 400.0;
	}

	public static double getImgHeigthProportion(File file)
			throws FileNotFoundException, IOException {
		BufferedImage oldBufferedImage = ImageIO
				.read(new FileInputStream(file));
		return oldBufferedImage.getHeight() / 400.0;
	}

	/**
	 * 复制文件或者目录,复制前后文件完全一样。
	 * 
	 * @param resFilePath
	 *            源文件路径
	 * @param distFolder
	 *            目标文件夹
	 * @IOException 当操作发生异常时抛出
	 */
	public static void copyFile(String resFilePath, String distFolder)
			throws IOException {
		File resFile = new File(resFilePath);
		File distFile = new File(distFolder);
		if (resFile.isDirectory()) {
			FileUtils.copyDirectoryToDirectory(resFile, distFile);
		} else if (resFile.isFile()) {
			FileUtils.copyFileToDirectory(resFile, distFile, true);
		}
	}

	public static void copyFile(File srcFile, File destFile) throws IOException {
		// 这里一定要用字节流，不要用字符流。因为上传过来的东西不知道是字节还是字符
		InputStream is = null;
		OutputStream os = null;

		try {
			is = new FileInputStream(srcFile);
			os = new FileOutputStream(destFile);

			// 使用字节数组作为中间变量，完成输入到输出的转换
			byte[] buffer = new byte[1024];
			int length = 0;
			while ((length = is.read(buffer)) > 0) {
				os.write(buffer, 0, length);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			is.close();

			os.close();
		}
	}

	/**
	 * 删除一个文件或者目录
	 * 
	 * @param targetPath
	 *            文件或者目录路径
	 * @IOException 当操作发生异常时抛出
	 */
	public static void deleteFile(String targetPath) throws IOException {
		File targetFile = new File(targetPath);
		if (targetFile.isDirectory()) {
			FileUtils.deleteDirectory(targetFile);
		} else if (targetFile.isFile()) {
			targetFile.delete();
		}
	}

	/**
	 * 移动文件或者目录,移动前后文件完全一样,如果目标文件夹不存在则创建。
	 * 
	 * @param resFilePath
	 *            源文件路径
	 * @param distFolder
	 *            目标文件夹
	 * @IOException 当操作发生异常时抛出
	 */
	public static void moveFile(String resFilePath, String distFolder)
			throws IOException {
		File resFile = new File(resFilePath);
		File distFile = new File(distFolder);
		if (resFile.isDirectory()) {
			FileUtils.moveDirectoryToDirectory(resFile, distFile, true);
		} else if (resFile.isFile()) {
			FileUtils.moveFileToDirectory(resFile, distFile, true);
		}
	}

	/**
	 * 重命名文件或文件夹
	 * 
	 * @param resFilePath
	 *            源文件路径
	 * @param newFileName
	 *            重命名
	 * @return 操作成功标识
	 */
	public static boolean renameFile(String resFilePath, String newFileName) {
		String newFilePath = StringUtil.formatPath(StringUtil
				.getParentPath(resFilePath)
				+ "/" + newFileName);
		File resFile = new File(resFilePath);
		File newFile = new File(newFilePath);
		return resFile.renameTo(newFile);
	}

	/**
	 * 读取文件或者目录的大小
	 * 
	 * @param distFilePath
	 *            目标文件或者文件夹
	 * @return 文件或者目录的大小，如果获取失败，则返回-1
	 */
	public static long genFileSize(String distFilePath) {
		File distFile = new File(distFilePath);
		if (distFile.isFile()) {
			return distFile.length();
		} else if (distFile.isDirectory()) {
			return FileUtils.sizeOfDirectory(distFile);
		}
		return -1L;
	}

	/**
	 * 判断一个文件是否存在
	 * 
	 * @param filePath
	 *            文件路径
	 * @return 存在返回true，否则返回false
	 */
	public static boolean isExist(String filePath) {
		return new File(filePath).exists();
	}

	/**
	 * 本地某个目录下的文件列表（不递归）
	 * 
	 * @param folder
	 *            ftp上的某个目录
	 * @param suffix
	 *            文件的后缀名（比如.mov.xml)
	 * @return 文件名称列表
	 */
	public static String[] listFilebySuffix(String folder, String suffix) {
		IOFileFilter fileFilter1 = new SuffixFileFilter(suffix);
		IOFileFilter fileFilter2 = new NotFileFilter(
				DirectoryFileFilter.INSTANCE);
		FilenameFilter filenameFilter = new AndFileFilter(fileFilter1,
				fileFilter2);
		return new File(folder).list(filenameFilter);
	}

	/**
	 * 将字符串写入指定文件(当指定的父路径中文件夹不存在时，会最大限度去创建，以保证保存成功！)
	 * 
	 * @param res
	 *            原字符串
	 * @param filePath
	 *            文件路径
	 * @return 成功标记
	 */
	public static boolean string2File(String res, String filePath) {
		boolean flag = true;
		BufferedReader bufferedReader = null;
		BufferedWriter bufferedWriter = null;
		try {
			File distFile = new File(filePath);
			if (!distFile.getParentFile().exists())
				distFile.getParentFile().mkdirs();
			bufferedReader = new BufferedReader(new StringReader(res));
			bufferedWriter = new BufferedWriter(new FileWriter(distFile));
			char buf[] = new char[1024]; // 字符缓冲区
			int len;
			while ((len = bufferedReader.read(buf)) != -1) {
				bufferedWriter.write(buf, 0, len);
			}
			bufferedWriter.flush();
			bufferedReader.close();
			bufferedWriter.close();
		} catch (IOException e) {
			flag = false;
			e.printStackTrace();
		}
		return flag;
	}

	/**
	 * 新建文件
	 * 
	 * @param filePathAndName
	 *            String 文件路径及名称 如c:/fqf.txt
	 * @param fileContent
	 *            String 文件内容
	 * @return boolean
	 * @throws IOException
	 */
	public static void newFile(String filePathAndName, String fileContent)
			throws IOException {
		String filePath = filePathAndName;
		filePath = filePath.toString();
		File myFilePath = new File(filePath);
		if (!myFilePath.exists()) {
			myFilePath.createNewFile();
		}
		FileWriter resultFile = new FileWriter(myFilePath);
		PrintWriter myFile = new PrintWriter(resultFile);
		String strContent = fileContent;
		myFile.println(strContent);
		resultFile.close();

	}
}
